<template>
    <view :class="ns.b()">
        <canvas id="canvas" class="canvas" type="2d"></canvas>
    </view>
</template>

<script setup lang="ts">
import lottie from "lottie-miniprogram";
import { useNamespace } from "@/hooks";

const ns = useNamespace("lottie");

/**
 * 定义组件触发的事件
 * @event ready - Lottie 动画初始化完成时触发
 * @event done - Lottie 动画播放完成时触发
 */
const emits = defineEmits(["ready", "done"]);

let canvasContext: any | null = null;

/**
 * 定义组件接收的属性
 * @property {number} width - 画布宽度，默认值为 0
 * @property {number} height - 画布高度，默认值为 0
 * @property {boolean} loop - 是否循环播放，默认值为 false
 * @property {boolean} autoplay - 是否自动播放，默认值为 false
 * @property {Object} animationData - Lottie 动画数据对象，默认值为 null
 */
const props = defineProps({
    width: {
        type: Number,
        default: 0
    },
    height: {
        type: Number,
        default: 0
    },
    loop: {
        type: Boolean,
        default: false
    },
    autoplay: {
        type: Boolean,
        default: false
    },
    animationData: {
        type: Object,
        default: null
    }
});

const instance = getCurrentInstance();

const instanceLottie = ref();

/**
 * 初始化 Lottie 动画实例
 * 配置并加载 Lottie 动画，绑定完成事件
 */
const onInitLottie = () => {
    const { loop, animationData, autoplay } = props;
    instanceLottie.value = lottie.loadAnimation({
        loop,
        autoplay,
        animationData,
        renderer: "canvas",
        rendererSettings: { context: canvasContext }
    });

    emits("ready");

    instanceLottie.value.addEventListener("complete", () => {
        instanceLottie.value.destroy();
        emits("done");
    });
};

/**
 * 组件挂载后初始化 Canvas 上下文和 Lottie 动画
 * 获取 Canvas 节点、设置上下文、配置分辨率并启动 Lottie 初始化
 */
onMounted(() => {
    nextTick(() => {
        uni.createSelectorQuery()
            .in(instance)
            .select("#canvas")
            .node((res) => {
                const canvas = res.node;
                canvasContext = canvas.getContext("2d");

                const systemInfo = uni.getSystemInfoSync();
                const dpr = systemInfo.pixelRatio;

                canvas.width = props.width * dpr;
                canvas.height = props.height * dpr;

                lottie.setup(canvas);

                onInitLottie();
            })
            .exec();
    });
});

/**
 * 播放 Lottie 动画
 */
const play = () => {
    instanceLottie.value.play();
};

/**
 * 停止 Lottie 动画
 */
const stop = () => {
    instanceLottie.value.stop();
};

/**
 * 暂停 Lottie 动画
 */
const pause = () => {
    instanceLottie.value.pause();
};

/**
 * 销毁 Lottie 动画实例
 */
const destroy = () => {
    instanceLottie.value.destroy();
};

/**
 * 暴露方法给父组件调用
 * @property {Function} play - 播放动画
 * @property {Function} stop - 停止动画
 * @property {Function} pause - 暂停动画
 * @property {Function} destroy - 销毁动画实例
 */
defineExpose({
    play,
    stop,
    pause,
    destroy
});
</script>

<style scoped lang="scss">
@import "./index";
</style>
